<?php
/*
   php pdf generation library
   Copyright (C) Potential Technologies 2002
   http://www.potentialtech.com

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

   $Id: phppdflib.class.php,v 1.16.2.1 2003/02/09 23:59:25 wmoran Exp $
*/

$signature = "phppdflib http://www.potentialtech.com/ppl.php Garennes" ;
//$signature = "Garennes" ;

class pdffile
{
    /* $objects is an array that stores the objects
     * that will become the pdf when ->generate()
     * is called.
     * The layout of ->objects does not directly
     * mimic the pdf format, although it is similar.
     * nextoid always holds the next available oid ( oid is short for object id )
     */
    var $objects, $nextoid;

    /* xreftable is an array containing data to
     * create the xref section (PDF calls it a refrerance table)
     */
    var $xreftable, $nextobj;

    /* These arrays allow quick translation between
     * pdflib OIDs and the final PDF OIDs (OID stands for object ids)
     */
    var $libtopdf, $pdftolib;

    /* Various data required during the pdf build */
    var $builddata;

    // Tracks the next page number
    var $nextpage;

    // Store the font width arrays here
    var $widths, $needsset;

    /* these are for column_page functions */
    var $columns, $pageid, $cur_col, $llop, $padding, $pagenode, $page_size;

    /* These are for bands */
    var $bands, $nextbandid, $bandpage, $bandline;

    /* Constructor function: is automatically called when the
     * object is created.  Used to set up the environment
     */
    function pdffile()
    {
        /* Per spec, obj 0 should always have a generation
         * number of 65535 and is always free
         */
        $this->xreftable[0]["gennum"] = 65535;
        $this->xreftable[0]["offset"] = 0;
        $this->xreftable[0]["free"] = "f";

        // Object #1 will always be the Document Catalog
        $this->xreftable[1]["gennum"] = 0;
        $this->xreftable[1]["free"] = "n";

        // Object #2 will always be the root pagenode
        $this->xreftable[2]["gennum"] = 0;
        $this->xreftable[2]["free"] = "n";
        $this->pdftolib[2] = 1;
        $this->libtopdf[1] = 2;

        // Object #3 is always the resource library
        $this->xreftable[3]["gennum"] = 0;
        $this->xreftable[3]["free"] = "n";

        /* nextoid starts at 2 because all
         * drawing functions return either the
         * object ID or FALSE on error, so we can't
         * return an OID of 0, because it equates
         * to false and error checking would think
         * the procedure failed
         */
        $this->nextoid = 2;
        $this->nextobj = 3;

        /* Bands start at 0 */
        $this->nextbandid = 0;
        $this->bandpage = false;

        // Pages start at 0
        $this->nextpage = 0;

        /* There have been unpredictable problems
         * with compression, so it's off by default
         */
        $this->builddata["compress"] = false;

        $this->needsset = true;
    }

/******************************************************
 * These functions are the public ones, they are the  *
 * way that the user will actually enter the data     *
 * that will become the pdf                           *
 ******************************************************/

    function set_compress($level)
    {
        if ( ! $level ) {
            $this->builddata["compress"] = false;
        } else {
            if ( $level < 10 ) {
                $this->builddata["compress"] = $level;
            } else {
                $this->builddata["compress"] = 9;
            }
        }
    }

    function draw_rectangle($top, $left, $bottom, $right, $parent, $attrib = array())
    {
        if ($this->objects[$parent]["type"] != "page") {
           return false;
        }
        $o = $this->_addnewoid();
        $this->_resolve_colors($n, $attrib);
        $this->objects[$o] = $n;
        if (isset($attrib["width"])) {
            $this->objects[$o]["width"] = $attrib["width"];
        }
        $this->objects[$o]["type"] = "rectangle";
        $this->objects[$o]["top"] = $top;
        $this->objects[$o]["left"] = $left;
        $this->objects[$o]["bottom"] = $bottom;
        $this->objects[$o]["right"] = $right;
        $this->objects[$o]["parent"] = $parent;
        return $o;
    }

    function draw_line($x, $y, $parent, $attrib = array())
    {
        if ($this->objects[$parent]["type"] != "page") {
           return false;
        }
        if (count($x) != count($y)) {
           return false;
        }
        $o = $this->_addnewoid();
        $this->_resolve_colors($n, $attrib);
        $this->objects[$o] = $n;
        if (isset($attrib["width"])) {
            $this->objects[$o]["width"] = $attrib["width"];
        }
        $this->objects[$o]["type"] = "line";
        $this->objects[$o]["x"] = $x;
        $this->objects[$o]["y"] = $y;
        $this->objects[$o]["parent"] = $parent;
        return $o;
    }

    // draw text
    function draw_text($left, $bottom, $text, $parent, $attrib = array())
    {
        if ($this->objects[$parent]["type"] != "page") {
           return False;
        }

        // Set default values
        $n["height"] = 12;
        $n["sred"] = 0;
        $n["sgreen"] = 0;
        $n["sblue"] = 0;
        $n["fred"] = 0;
        $n["fgreen"] = 0;
        $n["fblue"] = 0;
        $n["rotation"] = 0;
        $n["mode"] = 0;

        $font = isset($attrib["font"]) ? $attrib["font"] : "Helvetica";
        // Validate the font
        if (!($n["font"] = $this->_use_font($font))) {
            // Couldn't find/add the font
            return false;
        }
        if (isset($attrib["rotation"])) {
            $n["rotation"] = $attrib["rotation"];
        }
        if (isset($attrib["mode"])) {
            if ($attrib["mode"] != 0) {
                $n["mode"] = $attrib["mode"];
            } else {
                switch ($attrib["mode"]) {
                case "fill":
                    $n["mode"] = 0;
                    break;

                case "stroke":
                    $n["mode"] = 1;
                    break;

                case "fill+stroke":
                    $n["mode"] = 2;
                    break;
                }
            }
        }
        if (isset($attrib["height"]) && $attrib["height"] > 0) {
           $n["height"] = $attrib["height"];
        }
        $this->_resolve_colors($n, $attrib);
        $n["type"] = "texts";
        $n["left"] = $left;
        $n["bottom"] = $bottom;
        $n["text"] = $text;
        $n["parent"] = $parent;

        $o = $this->_addnewoid();
        $this->objects[$o] = $n;
        return $o;
    }

    function new_page($size)
    {
        switch ($size) {
        case "letter" :
            $o = $this->_addnewoid();
            $this->objects[$o]["height"] = 792;
            $this->objects[$o]["width"] = 612;
            break;

        case "legal" :
            $o = $this->_addnewoid();
            $this->objects[$o]["height"] = 1008;
            $this->objects[$o]["width"] = 612;
            break;

        case "executive" :
            $o = $this->_addnewoid();
            $this->objects[$o]["height"] = 720;
            $this->objects[$o]["width"] = 540;
            break;

        case "tabloid" :
            $o = $this->_addnewoid();
            $this->objects[$o]["height"] = 1224;
            $this->objects[$o]["width"] = 792;
            break;

        case "a3" :
            $o = $this->_addnewoid();
            $this->objects[$o]["height"] = 1188;
            $this->objects[$o]["width"] = 842;
            break;

        case "a4" :
            $o = $this->_addnewoid();
            $this->objects[$o]["height"] = 842;
            $this->objects[$o]["width"] = 595;
            break;

        case "a5" :
            $o = $this->_addnewoid();
            $this->objects[$o]["height"] = 598;
            $this->objects[$o]["width"] = 418;
            break;

        default :
            if (preg_match("/in/",$size)) {
                $o = $this->_addnewoid();
                $size = substr($size, 0, strlen($size) - 2);
                $dims = split("x",$size);
                $this->objects[$o]["height"] = ($dims[1] * 72);
                $this->objects[$o]["width"] = ($dims[0] * 72);
            } else {
                if (preg_match("/cm/",$size)) {
                    $o = $this->_addnewoid();
                    $size = substr($size, 0, strlen($size) - 2);
                    $dims = split("x",$size);
                    $this->objects[$o]["height"] = ($dims[1] * 28.346);
                    $this->objects[$o]["width"] = ($dims[0] * 28.346);
                } else {
                    return false;
                }

            }
        }
        $this->objects[$o]["type"] = "page";
        $this->objects[$o]["parent"] = 1;
        $this->objects[$o]["number"] = $this->nextpage;
        $this->nextpage ++;
        return $o;
    }

    function swap_pages($p1, $p2)
    {
        if ($this->objects[$p1]["type"] != "page" ||
            $this->objects[$p2]["type"] != "page") {
                return false;
        }
        $temp = $this->objects[$p1]["number"];
        $this->objects[$p1]["number"] = $this->objects[$p2]["number"];
        $this->objects[$p2]["number"] = $temp;
        return true;
    }

    function move_page_before($page, $infrontof)
    {
        if ($this->objects[$page]["type"] != "page" ||
            $this->objects[$infrontof]["type"] != "page") {
                return false;
        }
        if ($page == $infrontof) {
            return false;
        }
        $target = $this->objects[$infrontof]["number"];
        $leaving = $this->objects[$page]["number"];
        foreach ($this->objects as $id => $o) {
            if ($o["type"] == "page") {
                if ($target < $leaving) {
                    if ($o["number"] >= $target && $o["number"] < $leaving) {
                        $this->objects[$id]["number"]++;
                    }
                } else {
                    if ($o["number"] < $target && $o["number"] > $leaving) {
                        $this->objects[$id]["number"]--;
                    }
                }
            }
        }
        if ($target < $leaving) {
            $this->objects[$page]["number"] = $target;
        } else {
            $this->objects[$page]["number"] = $target - 1;
        }
        return true;
    }

    function new_font($identifier) {
        $n["type"] = "font";

        switch ($identifier) {
        /* The "standard" Type 1 fonts
         * These are "guaranteed" to be available
         * to the viewer application and don't
         * need embedded
         */
        case "Courier":
        case "Courier-Bold":
        case "Courier-Oblique":
        case "Courier-BoldOblique":
        case "Helvetica":
        case "Helvetica-Bold":
        case "Helvetica-Oblique":
        case "Helvetica-BoldOblique":
        case "Times-Roman":
        case "Times-Bold":
        case "Times-Italic":
        case "Times-BoldItalic":
        case "Symbol":
        case "ZapfDingbats":
            $o = $this->_addnewoid();
            $this->builddata["fonts"][$o] = $identifier;
            $n["subtype"] = "Type1";
            $n["basefont"] = $identifier;
            break;

        default:
            if ( $this->objects[$identifier]["type"] != "fontembed" ) {
                return false;
            } else {
                // Not ready yet
                return false;
            }
        }
        $this->objects[$o] = $n;
        return $o;
    }

    function generate()
    {
        /* Preprocess objects to see if they can
         * be combined into a single stream
         * We scan through each page, and create
         * a multistream object out of all viable
         * child objects
         */
        
        $temparray = $this->objects;
        foreach ($this->objects as $oid => $def) {
            if ( $def["type"] == "page" ) {
                unset($temp);
                $temp['data'] = "";
                reset($temparray);
                while ( list ($liboid, $obj) = each($temparray) ) {
                    if (isset($obj["parent"]) && $obj["parent"] == $oid) {
                        switch ($obj["type"]) {
                        case "texts" :
                            $temp["data"] .= $this->_make_text($liboid);
                            $this->objects[$liboid]["type"] = "null";
                            $this->objects[$liboid]["parent"] = -1;
                            break;

                        case "rectangle" :
                            $temp["data"] .= $this->_make_rect($liboid);
                            $this->objects[$liboid]["type"] = "null";
                            $this->objects[$liboid]["parent"] = -1;
                            break;

                        case "iplace" :
                            $temp["data"] .= $this->_place_raw_image($liboid);
                            $this->objects[$liboid]["type"] = "null";
                            $this->objects[$liboid]["parent"] = -1;
                            break;

                        case "line" :
                            $temp["data"] .= $this->_make_line($liboid);
                            $this->objects[$liboid]["type"] = "null";
                            $this->objects[$liboid]["parent"] = -1;
                            break;
                        }
                    }
                }
                if (strlen($temp["data"]) > 0) {
                    // this line takes the next available oid
                    $o = $this->_addnewoid();
                    $temp["type"] = "mstream";
                    $temp["parent"] = $oid;
                    $this->objects[$o] = $temp;
                }
            }
        }
        unset($temparray);

        // Generate a list of PDF object IDs to
        // use and map them to phppdflib IDs
        foreach ( $this->objects as $oid => $properties ) {
            if ( $this->_becomes_object( $properties["type"] ) ) {
                $o = $this->_addtoxreftable(0,0);
                $this->libtopdf[$oid] = $o;
                $this->pdftolib[$o] = $oid;
            }
        }

        /* First characters represent the version
         * of the PDF spec to conform to.
         * The PDF spec recommends that the next
         * four bytes be a comment containing four
         * non-ASCII characters, to convince
         * (for example) ftp programs that this is
         * a binary file
         */
        $os = "%PDF-1.3%\xe2\xe3\xcf\xd3\x0a";

        // Create the Document Catalog
        $carray["Type"] = "/Catalog";
        $carray["Pages"] = "2 0 R";
        $temp = $this->_makedictionary("", $carray);
        $temp = "1 0 obj" . $temp . "endobj\x0a";
        $this->xreftable[1]["offset"] = strlen($os);
        $os .= $temp;

        // Create the root page node
        unset($carray);
        $kids = $this->_order_pages(2);
        $this->xreftable[2]["offset"] = strlen($os);
        $os .= "2 0 " . $this->_makepagenode($kids, "" ) . "\x0a";

        /* Create a resource dictionary for the entire
         * PDF file.  This may not be the most efficient
         * way to store it, but it makes the code simple.
         * At some point, we should analyze performance
         * and see if it's worth splitting the resource
         * dictionary up
         */
        unset($temp);
        unset($carray);
        if (count($this->builddata["fonts"]) > 0) {
            foreach ($this->builddata["fonts"] as $id => $base) {
                $ta["F$id"] = $this->libtopdf[$id] . " 0 R";
            }
            $temp["Font"] = $this->_makedictionary("", $ta );
        }
        If (Is_Array ($this->objects))
         {
          reset($this->objects);
          while (list($id, $obj) = each($this->objects)) {
              if ($obj["type"] == "image") {
                  $xol["Img$id"] = $this->libtopdf[$id] . " 0 R";
              }
          }
         }
        if ( isset($xol) && count($xol) > 0 ) {
            $temp["XObject"] = $this->_makedictionary("", $xol);
        }
        $this->xreftable[3]["offset"] = strlen($os);
        $os .= "3 0 obj";
        if (isset($temp)) {
            $os .= $this->_makedictionary("", $temp);
        } else {
            $os .= "<<>>";
        }
        $os .= " endobj\x0a";
        
        // Go through and add the rest of the objects
        foreach ( $this->pdftolib as $pdfoid => $liboid ) {
            if ($pdfoid < 4) {
                continue;
            }
            // Set the location of the start
            $this->xreftable[$pdfoid]["offset"] = strlen($os);
            switch ( $this->objects[$liboid]["type"] ) {
            case "page":
                $kids = $this->_get_kids($pdfoid);
                $os .= $pdfoid . " 0 ";
                $os .= $this->_makepage($this->objects[$liboid]["parent"],
                                        $kids, $liboid);
                break;

            case "rectangle":
                $os .= $pdfoid . " 0 obj";
                $os .= $this->_streamify("", $this->_make_rect($liboid));
                $os .= " endobj";
                break;

            case "line":
                $os .= $pdfoid . " 0 obj";
                $os .= $this->_streamify("", $this->_make_line($liboid));
                $os .= " endobj";
                break;

            case "texts":
                $os .= $pdfoid . " 0 obj";
                $temp = $this->_make_text($liboid);
                $os .= $this->_streamify("", $temp ) . " endobj";
                break;

            case "mstream":
                $os .= $pdfoid . " 0 obj" .
                       $this->_streamify("", trim($this->objects[$liboid]["data"])) .
                       " endobj";
                break;

            case "image":
                $os .= $pdfoid . " 0 obj";
                $os .= $this->_make_raw_image($liboid);
                $os .= " endobj";
                break;

            case "iplace":
                $os .= $pdfoid . " 0 obj";
                $os .= $this->_streamify("", $this->_place_raw_image($liboid));
                $os .= " endobj";
                break;

            case "font" :
                $os .= $pdfoid . " 0 obj";
                unset ( $temp );
                $temp["Type"] = "/Font";
                $temp["Subtype"] = "/" . $this->objects[$liboid]["subtype"];
                $temp["BaseFont"] = "/" . $this->objects[$liboid]["basefont"];
                $temp["Encoding"] = "/WinAnsiEncoding";
                $temp["Name"] = "/F$liboid";
                $os .= $this->_makedictionary( "", $temp );
                $os .= " endobj";
                break;
            }
            $os .= "\x0a";
        }

        // Create an Info entry
        $info = $this->_addtoxreftable(0,0);
        $this->xreftable[$info]["offset"] = strlen($os);
        unset($temp);
	Global $signature ;
        $temp["Producer"] =
            $this->_stringify($signature);
        $os .= $info . " 0 obj" . $this->_makedictionary("", $temp) . " endobj\x0a";

        // Create the xref table
        $this->builddata["startxref"] = strlen($os);
        $os .= $this->_genxreftable();

        // Create document trailer
        $os .= $this->_maketrailer($info);

        // Required end of file marker
        $os .= "%%EOF\x0a";

        return $os;
    }

    function column_start($columns, $size = "letter", $padding = 36)
    {
        $this->columns = $columns;
        $this->padding = $padding;
        $this->pagenode = 1;
        $this->page_size = $size;
        $this->column_new_page();
    }

    function column_line($text, $height)
    {
        if ( !is_array($text) ) {
            $temp = $text;
            unset($text);
            $text[] = $temp;
            $temp = $height;
            unset($height);
            $height[] = $temp;
        }
        $fullh = 0;
        foreach ($height as $temp) {
            $fullh += $temp + 2;
        }
        if ($fullh > ($this->objects[$this->pageid]["height"] - 2 * $this->padding) ) {
            return false;
        }
        if ($fullh > ($this->llop - $this->padding)) {
            $this->column_next();
        }

        $lrpost = $this->padding + ( $this->cur_col *
                  ( ($this->objects[$this->pageid]["width"] -
                  ( 2*$this->padding )) / $this->columns ));

        foreach ( $text as $index => $string ) {
            if ($height[$index] > 0) {
                $this->llop = ($this->llop - ($height[$index] + 2));
                $params["height"] = $height[$index];
                $this->draw_text($lrpost,
                                 $this->llop,
                                 $string,
                                 $this->pageid,
                                 $params);
            }
        }

        return true;
    }

    function column_next()
    {
        $this->cur_col ++;
        if ($this->cur_col == $this->columns) {
            $this->column_new_page();
        }
        $this->_column_top();
    }

    function column_new_page()
    {
        $this->pageid = $this->new_page($this->page_size, $this->pagenode);
        $this->cur_col = 0;
        $this->_column_top();
    }

    /* Creates a new band and returns its band ID */
    function band_new()
    {
        $temp = $this->nextbandid;
        $this->bands[$temp]["next"] = 0;
        $this->nextbandid ++;
        return $temp;
    }

    function band_height($bandid, $height)
    {
        $this->bands[$bandid]["height"] = $height;
        return $height;
    }

    function band_add_box($bandid, $bottom, $left, $top, $right, $attrib = "")
    {
        if (is_array($attrib)) {
            $temp = $attrib;
        }
        $temp["type"] = "rectangle";
        $temp["top"] = $top;
        $temp["left"] = $left;
        $temp["bottom"] = $bottom;
        $temp["right"] = $right;
        return $this->_band_add_object($temp, $bandid);
    }

    function band_add_label($bandid, $left, $bottom, $text, $height, $font = "Helvetica")
    {
        $temp["type"] = "texts";
        $temp["left"] = $left;
        $temp["bottom"] = $bottom;
        $temp["text"] = $text;
        $temp["font"] = $font;
        $temp["height"] = $height;
        return $this->_band_add_object($temp, $bandid);
    }

    function band_add_field($bandid, $left, $bottom, $name,
                            $height, $default = "", $font = "Helvetica")
    {
        $temp["type"] = "field";
        $temp["left"] = $left;
        $temp["bottom"] = $bottom;
        $temp["name"] = $name;
        $temp["font"] = $font;
        $temp["height"] = $height;
        $temp["default"] = $default;
        $oid = $this->_band_add_object($temp, $bandid);
    }

    function band_place($bandid, $data, $page, $left, $bottom)
    {
        foreach( $this->bands[$bandid]["objects"] as $o ) {
            switch ($o["type"]) {
            case "rectangle" :
                $this->draw_rectangle($bottom + $o["top"],
                                      $left + $o["left"],
                                      $bottom + $o["bottom"],
                                      $left + $o["right"],
                                      $page,
                                      $o);
                break;

            case "texts" :
                $params["height"] = $o["height"];
                $params["font"] = $o["font"];
                $this->draw_text($left + $o["left"],
                                 $bottom + $o["bottom"],
                                 $o["text"],
                                 $page,
                                 $params);
                break;

            case "field" :
                $temp = empty($data[$o["name"]]) ? $o["default"] : $data[$o["name"]];
                $params["height"] = $o["height"];
                $params["font"] = $o["font"];
                $this->draw_text($left + $o["left"],
                                 $bottom + $o["bottom"],
                                 $temp,
                                 $page,
                                 $params);
            }
        }
    }

    function band_line($bandid, $data)
    {
        if ( $this->bandpage == false ) {
            // This is the first call to band_line
            $this->band_new_page("letter");
        }
        // Move down one band height
        $this->bandline -= $this->bands[$bandid]["height"];
        if ($this->bandline < 36) {
            // We're out of room on this page
            $this->band_new_page("letter");
            $this->bandline -= $this->bands[$bandid]["height"];
        }
        // Place the band ...
        $this->band_place($bandid, $data, $this->bandpage, 36, $this->bandline);

        return $this->bandpage;
    }

    function band_new_page($size)
    {
        $this->bandpage = $this->new_page($size);
        // Fixed value for 11" page - 1/2" margin
        $this->bandline = 756;
    }

    function band_serialize($bandid)
    {
        return serialize($this->bands[$bandid]);
    }

    function band_unserialize($banddata)
    {
        $newband = $this->band_new();
        $this->bands[$newband] = unserialize($banddata);
        return $newband;
    }

/* The much requested graphics support starts here */

    function jfif_embed($data)
    {
        /* Sanity check: Check magic numbers to see if
         * this is really a JFIF stream
         */
        if ( substr($data, 0, 4) != "\xff\xd8\xff\xe0" ||
             substr($data, 6, 4) != "JFIF" ) {
            // This is not in JFIF format
            return false;
        }

        /* Now we'll scan through all the markers in the
         * JFIF and extract whatever data we need from them
         * We're not being terribly anal about validating
         * the structure of the JFIF, so a corrupt stream
         * could have very unpredictable results
         */
        // Default values
        $pos = 0;
        $size = strlen($data);

        while ( $pos < $size ) {
            $marker = substr($data, $pos + 1, 1);
            // Just skip these markers
            if ($marker == "\xd8" || $marker == "\xd9" || $marker == "\x01") {
                $pos += 2;
                continue;
            }
            if ($marker == "\xff") {
                $pos ++;
                continue;
            }

            switch ($marker) {
            // Start of frame
            // Baseline
            case "\xc0":
            // Extended sequential
            case "\xc1":
            // Differential sequential
            case "\xc5":
            // Progressive
            case "\xc2":
            // differential progressive
            case "\xc6":
            // Lossless
            case "\xc3":
            // differential lossless
            case "\xc7":
            // Arithmetic encoded
            case "\xc9":
            case "\xca":
            case "\xcb":
            case "\xcd":
            case "\xce":
            case "\xcf":
                $precision = $this->_int_val(substr($data, $pos + 4, 1));
                $height = $this->_int_val(substr($data, $pos + 5, 2));
                $width = $this->_int_val(substr($data, $pos + 7, 2));
                $numcomp = $this->_int_val(substr($data, $pos + 9, 1));
                if ( $numcomp != 3 && $numcomp != 1 ) {
                    // Abort if we aren't encoded as B&W or YCbCr
                    return false;
                }
                $pos += 2 + $this->_int_val(substr($data, $pos + 2, 2));
                break 2;
            }

            /* All marker identifications continue the
             * loop, thus if we got here, we need to skip
             * this marker as we don't understand it.
             */
            $pos += 2 + $this->_int_val(substr($data, $pos + 2, 2));
        }
        $cspace = $numcomp == 1 ? "/DeviceGray" : "/DeviceRGB";
        return $this->image_raw_embed($data,
                                      $cspace,
                                      $precision,
                                      $height,
                                      $width,
                                      "/DCTDecode");
    }

    function image_raw_embed($data, $cspace, $bpc, $height, $width, $filter = "")
    {
        $o = $this->_addnewoid();
        $t["data"] = $data;
        $t["colorspace"] = $cspace;
        $t["bpc"] = $bpc;
        $t["type"] = "image";
        $t["height"] = $height;
        $t["width"] = $width;
        $t["filter"] = $filter;
        $this->objects[$o] = $t;
        return $o;
    }

    function get_image_size($id)
    {
     if (isset ($this->objects[$id]['type']))
      {
        if ($this->objects[$id]['type'] != 'image') {
            return false;
        }
        $r['width'] = $this->objects[$id]['width'];
        $r['height'] = $this->objects[$id]['height'];
        return $r;
      }
     else { return false ; }
    }

    function image_raw_place($oid, $bottom, $left, $parent, $scale = 1, $rotation = 0)
    {
        if ($this->objects[$oid]["type"] != "image") {
            return false;
        }
        if ($this->objects[$parent]["type"] != "page") {
            return false;
        }
        $o = $this->_addnewoid();
        $t["type"] = "iplace";
        $t["bottom"] = $bottom;
        $t["left"] = $left;
        $t["parent"] = $parent;
        $t["xscale"] = $scale;
        $t["yscale"] = $scale;
        $t["rotation"] = $rotation;
        $t["image"] = $oid;
        $this->objects[$o] = $t;
        return $o;
    }

    function image_place($oid, $bottom, $left, $parent, $scale = 1, $rotation = 0)
    {
     if (isset ($this->objects[$oid]["type"]))
      {
        if ($this->objects[$oid]["type"] != "image") {
            return false;
        }
        if ($this->objects[$parent]["type"] != "page") {
            return false;
        }

        $o = $this->_addnewoid();
        $t["type"] = "iplace";
        $t["bottom"] = $bottom;
        $t["left"] = $left;
        $t["parent"] = $parent;
        // find out what the image size should be
        $width = $this->objects[$oid]["width"];
        $height = $this->objects[$oid]["height"];
        if (is_array($scale)) {
            $t["xscale"] = $scale["x"] * $width;
            $t["yscale"] = $scale["y"] * $height;
        } else {
            $t["xscale"] = $scale * $width;
            $t["yscale"] = $scale * $height;
        }
        $t["rotation"] = $rotation;
        $t["image"] = $oid;
        $this->objects[$o] = $t;
        return $o;
      }
     else { return false; }
    }

    function strlen ( $string , $params  = false)
    {
        if ($this->needsset) {
            $this->needsset = false;
            $this->widths['Symbol']= array ( 32 => 250, 33 => 333, 34 => 713, 35 => 500, 36 => 549,
                                   37 => 833, 38 => 778, 39 => 439, 40 => 333, 41 => 333,
                                   42 => 500, 43 => 549, 44 => 250, 45 => 549, 46 => 250,
                                   47 => 278, 48 => 500, 49 => 500, 50 => 500, 51 => 500,
                                   52 => 500, 53 => 500, 54 => 500, 55 => 500, 56 => 500,
                                   57 => 500, 58 => 278, 59 => 278, 60 => 549, 61 => 549,
                                   62 => 549, 63 => 444, 64 => 549, 65 => 722, 66 => 667,
                                   67 => 722, 68 => 612, 69 => 611, 70 => 763, 71 => 603,
                                   72 => 722, 73 => 333, 74 => 631, 75 => 722, 76 => 686,
                                   77 => 889, 78 => 722, 79 => 722, 80 => 768, 81 => 741,
                                   82 => 556, 83 => 592, 84 => 611, 85 => 690, 86 => 439,
                                   87 => 768, 88 => 645, 89 => 795, 90 => 611, 91 => 333,
                                   92 => 863, 93 => 333, 94 => 658, 95 => 500, 96 => 500,
                                   97 => 631, 98 => 549, 99 => 549, 100 => 494, 101 => 439,
                                   102 => 521, 103 => 411, 104 => 603, 105 => 329, 106 => 603,
                                   107 => 549, 108 => 549, 109 => 576, 110 => 521, 111 => 549,
                                   112 => 549, 113 => 521, 114 => 549, 115 => 603, 116 => 439,
                                   117 => 576, 118 => 713, 119 => 686, 120 => 493, 121 => 686,
                                   122 => 494, 123 => 480, 124 => 200, 125 => 480, 126 => 549,
                                   161 => 620, 162 => 247, 163 => 549, 164 => 167, 165 => 713,
                                   166 => 500, 167 => 753, 168 => 753, 169 => 753, 170 => 753,
                                   171 => 1042, 172 => 987, 173 => 603, 174 => 987, 175 => 603,
                                   176 => 400, 177 => 549, 178 => 411, 179 => 549, 180 => 549,
                                   181 => 713, 182 => 494, 183 => 460, 184 => 549, 185 => 549,
                                   186 => 549, 187 => 549, 188 => 1000, 189 => 603, 190 => 1000,
                                   191 => 658, 192 => 823, 193 => 686, 194 => 795, 195 => 987,
                                   196 => 768, 197 => 768, 198 => 823, 199 => 768, 200 => 768,
                                   201 => 713, 202 => 713, 203 => 713, 204 => 713, 205 => 713,
                                   206 => 713, 207 => 713, 208 => 768, 209 => 713, 210 => 790,
                                   211 => 790, 212 => 890, 213 => 823, 214 => 549, 215 => 250,
                                   216 => 713, 217 => 603, 218 => 603, 219 => 1042, 220 => 987,
                                   221 => 603, 222 => 987, 223 => 603, 224 => 494, 225 => 329,
                                   226 => 790, 227 => 790, 228 => 786, 229 => 713, 230 => 384,
                                   231 => 384, 232 => 384, 233 => 384, 234 => 384, 235 => 384,
                                   236 => 494, 237 => 494, 238 => 494, 239 => 494, 241 => 329,
                                   242 => 274, 243 => 686, 244 => 686, 245 => 686, 246 => 384,
                                   247 => 384, 248 => 384, 249 => 384, 250 => 384, 251 => 384,
                                   252 => 494, 253 => 494, 254 => 494 );
            $this->widths['Dingbats'] = array (32 => 278, 33 => 974, 34 => 961, 35 => 974, 36 => 980,
                                     37 => 719, 38 => 789, 39 => 790, 40 => 791, 41 => 690,
                                     42 => 960, 43 => 939, 44 => 549, 45 => 855, 46 => 911,
                                     47 => 933, 48 => 911, 49 => 945, 50 => 974, 51 => 755,
                                     52 => 846, 53 => 762, 54 => 761, 55 => 571, 56 => 677,
                                     57 => 763, 58 => 760, 59 => 759, 60 => 754, 61 => 494,
                                     62 => 552, 63 => 537, 64 => 577, 65 => 692, 66 => 786,
                                     67 => 788, 68 => 788, 69 => 790, 70 => 793, 71 => 794,
                                     72 => 816, 73 => 823, 74 => 789, 75 => 841, 76 => 823,
                                     77 => 833, 78 => 816, 79 => 831, 80 => 923, 81 => 744,
                                     82 => 723, 83 => 749, 84 => 790, 85 => 792, 86 => 695,
                                     87 => 776, 88 => 768, 89 => 792, 90 => 759, 91 => 707,
                                     92 => 708, 93 => 682, 94 => 701, 95 => 826, 96 => 815,
                                     97 => 789, 98 => 789, 99 => 707, 100 => 687, 101 => 696,
                                     102 => 689, 103 => 786, 104 => 787, 105 => 713, 106 => 791,
                                     107 => 785, 108 => 791, 109 => 873, 110 => 761, 111 => 762,
                                     112 => 762, 113 => 759, 114 => 759, 115 => 892, 116 => 892,
                                     117 => 788, 118 => 784, 119 => 438, 120 => 138, 121 => 277,
                                     122 => 415, 123 => 392, 124 => 392, 125 => 668, 126 => 668,
                                     161 => 732, 162 => 544, 163 => 544, 164 => 910, 165 => 667,
                                     166 => 760, 167 => 760, 168 => 776, 169 => 595, 170 => 694,
                                     171 => 626, 172 => 788, 173 => 788, 174 => 788, 175 => 788,
                                     176 => 788, 177 => 788, 178 => 788, 179 => 788, 180 => 788,
                                     181 => 788, 182 => 788, 183 => 788, 184 => 788, 185 => 788,
                                     186 => 788, 187 => 788, 188 => 788, 189 => 788, 190 => 788,
                                     191 => 788, 192 => 788, 193 => 788, 194 => 788, 195 => 788,
                                     196 => 788, 197 => 788, 198 => 788, 199 => 788, 200 => 788,
                                     201 => 788, 202 => 788, 203 => 788, 204 => 788, 205 => 788,
                                     206 => 788, 207 => 788, 208 => 788, 209 => 788, 210 => 788,
                                     211 => 788, 212 => 894, 213 => 838, 214 => 1016, 215 => 458,
                                     216 => 748, 217 => 924, 218 => 748, 219 => 918, 220 => 927,
                                     221 => 928, 222 => 928, 223 => 834, 224 => 873, 225 => 828,
                                     226 => 924, 227 => 924, 228 => 917, 229 => 930, 230 => 931,
                                     231 => 463, 232 => 883, 233 => 836, 234 => 836, 235 => 867,
                                     236 => 867, 237 => 696, 238 => 696, 239 => 874, 241 => 874,
                                     242 => 760, 243 => 946, 244 => 771, 245 => 865, 246 => 771,
                                     247 => 888, 248 => 967, 249 => 888, 250 => 831, 251 => 873,
                                     252 => 927, 253 => 970, 254 => 918);
            $this->widths['Helvetica-Bold'] = array (32 => 278, 33 => 333, 34 => 474, 35 => 556,
                                           36 => 556, 37 => 889, 38 => 722, 39 => 278,
                                           40 => 333, 41 => 333, 42 => 389, 43 => 584,
                                           44 => 278, 45 => 333, 46 => 278, 47 => 278,
                                           48 => 556, 49 => 556, 50 => 556, 51 => 556,
                                           52 => 556, 53 => 556, 54 => 556, 55 => 556,
                                           56 => 556, 57 => 556, 58 => 333, 59 => 333,
                                           60 => 584, 61 => 584, 62 => 584, 63 => 611,
                                           64 => 975, 65 => 722, 66 => 722, 67 => 722,
                                           68 => 722, 69 => 667, 70 => 611, 71 => 778,
                                           72 => 722, 73 => 278, 74 => 556, 75 => 722,
                                           76 => 611, 77 => 833, 78 => 722, 79 => 778,
                                           80 => 667, 81 => 778, 82 => 722, 83 => 667,
                                           84 => 611, 85 => 722, 86 => 667, 87 => 944,
                                           88 => 667, 89 => 667, 90 => 611, 91 => 333,
                                           92 => 278, 93 => 333, 94 => 584, 95 => 556,
                                           96 => 278, 97 => 556, 98 => 611, 99 => 556,
                                           100 => 611, 101 => 556, 102 => 333, 103 => 611,
                                           104 => 611, 105 => 278, 106 => 278, 107 => 556,
                                           108 => 278, 109 => 889, 110 => 611, 111 => 611,
                                           112 => 611, 113 => 611, 114 => 389, 115 => 556,
                                           116 => 333, 117 => 611, 118 => 556, 119 => 778,
                                           120 => 556, 121 => 556, 122 => 500, 123 => 389,
                                           124 => 280, 125 => 389, 126 => 584, 161 => 333,
                                           162 => 556, 163 => 556, 164 => 167, 165 => 556,
                                           166 => 556, 167 => 556, 168 => 556, 169 => 238,
                                           170 => 500, 171 => 556, 172 => 333, 173 => 333,
                                           174 => 611, 175 => 611, 177 => 556, 178 => 556,
                                           179 => 556, 180 => 278, 182 => 556, 183 => 350,
                                           184 => 278, 185 => 500, 186 => 500, 187 => 556,
                                           188 => 1000, 189 => 1000, 191 => 611, 193 => 333,
                                           194 => 333, 195 => 333, 196 => 333, 197 => 333,
                                           198 => 333, 199 => 333, 200 => 333, 202 => 333,
                                           203 => 333, 205 => 333, 206 => 333, 207 => 333,
                                           208 => 1000, 225 => 1000, 227 => 370, 232 => 611,
                                           233 => 778, 234 => 1000, 235 => 365, 241 => 889,
                                           245 => 278, 248 => 278, 249 => 611, 250 => 944,
                                           251 => 611 );
            $this->widths['Helvetica'] = array (32 => 278, 33 => 278, 34 => 355, 35 => 556, 36 => 556,
                                      37 => 889, 38 => 667, 39 => 222, 40 => 333, 41 => 333,
                                      42 => 389, 43 => 584, 44 => 278, 45 => 333, 46 => 278,
                                      47 => 278, 48 => 556, 49 => 556, 50 => 556, 51 => 556,
                                      52 => 556, 53 => 556, 54 => 556, 55 => 556, 56 => 556,
                                      57 => 556, 58 => 278, 59 => 278, 60 => 584, 61 => 584,
                                      62 => 584, 63 => 556, 64 => 1015, 65 => 667, 66 => 667,
                                      67 => 722, 68 => 722, 69 => 667, 70 => 611, 71 => 778,
                                      72 => 722, 73 => 278, 74 => 500, 75 => 667, 76 => 556,
                                      77 => 833, 78 => 722, 79 => 778, 80 => 667, 81 => 778,
                                      82 => 722, 83 => 667, 84 => 611, 85 => 722, 86 => 667,
                                      87 => 944, 88 => 667, 89 => 667, 90 => 611, 91 => 278,
                                      92 => 278, 93 => 278, 94 => 469, 95 => 556, 96 => 222,
                                      97 => 556, 98 => 556, 99 => 500, 100 => 556, 101 => 556,
                                      102 => 278, 103 => 556, 104 => 556, 105 => 222, 106 => 222,
                                      107 => 500, 108 => 222, 109 => 833, 110 => 556, 111 => 556,
                                      112 => 556, 113 => 556, 114 => 333, 115 => 500, 116 => 278,
                                      117 => 556, 118 => 500, 119 => 722, 120 => 500, 121 => 500,
                                      122 => 500, 123 => 334, 124 => 260, 125 => 334, 126 => 584,
                                      161 => 333, 162 => 556, 163 => 556, 164 => 167, 165 => 556,
                                      166 => 556, 167 => 556, 168 => 556, 169 => 191, 170 => 333,
                                      171 => 556, 172 => 333, 173 => 333, 174 => 500, 175 => 500,
                                      177 => 556, 178 => 556, 179 => 556, 180 => 278, 182 => 537,
                                      183 => 350, 184 => 222, 185 => 333, 186 => 333, 187 => 556,
                                      188 => 1000, 189 => 1000, 191 => 611, 193 => 333, 194 => 333,
                                      195 => 333, 196 => 333, 197 => 333, 198 => 333, 199 => 333,
                                      200 => 333, 202 => 333, 203 => 333, 205 => 333, 206 => 333,
                                      207 => 333, 208 => 1000, 225 => 1000, 227 => 370, 232 => 556,
                                      233 => 778, 234 => 1000, 235 => 365, 241 => 889, 245 => 278,
                                      248 => 222, 249 => 611, 250 => 944, 251 => 611 );
            $this->widths['Times'] = array (32 => 250, 33 => 333, 34 => 408, 35 => 500, 36 => 500,
                                  37 => 833, 38 => 778, 39 => 333, 40 => 333, 41 => 333,
                                  42 => 500, 43 => 564, 44 => 250, 45 => 333, 46 => 250,
                                  47 => 278, 48 => 500, 49 => 500, 50 => 500, 51 => 500,
                                  52 => 500, 53 => 500, 54 => 500, 55 => 500, 56 => 500,
                                  57 => 500, 58 => 278, 59 => 278, 60 => 564, 61 => 564,
                                  62 => 564, 63 => 444, 64 => 921, 65 => 722, 66 => 667,
                                  67 => 667, 68 => 722, 69 => 611, 70 => 556, 71 => 722,
                                  72 => 722, 73 => 333, 74 => 389, 75 => 722, 76 => 611,
                                  77 => 889, 78 => 722, 79 => 722, 80 => 556, 81 => 722,
                                  82 => 667, 83 => 556, 84 => 611, 85 => 722, 86 => 722,
                                  87 => 944, 88 => 722, 89 => 722, 90 => 611, 91 => 333,
                                  92 => 278, 93 => 333, 94 => 469, 95 => 500, 96 => 333,
                                  97 => 444, 98 => 500, 99 => 444, 100 => 500, 101 => 444,
                                  102 => 333, 103 => 500, 104 => 500, 105 => 278, 106 => 278,
                                  107 => 500, 108 => 278, 109 => 778, 110 => 500, 111 => 500,
                                  112 => 500, 113 => 500, 114 => 333, 115 => 389, 116 => 278,
                                  117 => 500, 118 => 500, 119 => 722, 120 => 500, 121 => 500,
                                  122 => 444, 123 => 480, 124 => 200, 125 => 480, 126 => 541,
                                  161 => 333, 162 => 500, 163 => 500, 164 => 167, 165 => 500,
                                  166 => 500, 167 => 500, 168 => 500, 169 => 180, 170 => 444,
                                  171 => 500, 172 => 333, 173 => 333, 174 => 556, 175 => 556,
                                  177 => 500, 178 => 500, 179 => 500, 180 => 250, 182 => 453,
                                  183 => 350, 184 => 333, 185 => 444, 186 => 444, 187 => 500,
                                  188 => 1000, 189 => 1000, 191 => 444, 193 => 333, 194 => 333,
                                  195 => 333, 196 => 333, 197 => 333, 198 => 333, 199 => 333,
                                  200 => 333, 202 => 333, 203 => 333, 205 => 333, 206 => 333,
                                  207 => 333, 208 => 1000, 225 => 889, 227 => 276, 232 => 611,
                                  233 => 722, 234 => 889, 235 => 310, 241 => 667, 245 => 278,
                                  248 => 278, 249 => 500, 250 => 722, 251 => 500);
            $this->widths['Times-Bold'] = array (32 => 250, 33 => 333, 34 => 555, 35 => 500, 36 => 500,
                                       37 => 1000, 38 => 833, 39 => 333, 40 => 333, 41 => 333,
                                       42 => 500, 43 => 570, 44 => 250, 45 => 333, 46 => 250,
                                       47 => 278, 48 => 500, 49 => 500, 50 => 500, 51 => 500,
                                       52 => 500, 53 => 500, 54 => 500, 55 => 500, 56 => 500,
                                       57 => 500, 58 => 333, 59 => 333, 60 => 570, 61 => 570,
                                       62 => 570, 63 => 500, 64 => 930, 65 => 722, 66 => 667,
                                       67 => 722, 68 => 722, 69 => 667, 70 => 611, 71 => 778,
                                       72 => 778, 73 => 389, 74 => 500, 75 => 778, 76 => 667,
                                       77 => 944, 78 => 722, 79 => 778, 80 => 611, 81 => 778,
                                       82 => 722, 83 => 556, 84 => 667, 85 => 722, 86 => 722,
                                       87 => 1000, 88 => 722, 89 => 722, 90 => 667, 91 => 333,
                                       92 => 278, 93 => 333, 94 => 581, 95 => 500, 96 => 333,
                                       97 => 500, 98 => 556, 99 => 444, 100 => 556, 101 => 444,
                                       102 => 333, 103 => 500, 104 => 556, 105 => 278, 106 => 333,
                                       107 => 556, 108 => 278, 109 => 833, 110 => 556, 111 => 500,
                                       112 => 556, 113 => 556, 114 => 444, 115 => 389, 116 => 333,
                                       117 => 556, 118 => 500, 119 => 722, 120 => 500, 121 => 500,
                                       122 => 444, 123 => 394, 124 => 220, 125 => 394, 126 => 520,
                                       161 => 333, 162 => 500, 163 => 500, 164 => 167, 165 => 500,
                                       166 => 500, 167 => 500, 168 => 500, 169 => 278, 170 => 500,
                                       171 => 500, 172 => 333, 173 => 333, 174 => 556, 175 => 556,
                                       177 => 500, 178 => 500, 179 => 500, 180 => 250, 182 => 540,
                                       183 => 350, 184 => 333, 185 => 500, 186 => 500, 187 => 500,
                                       188 => 1000, 189 => 1000, 191 => 500, 193 => 333, 194 => 333,
                                       195 => 333, 196 => 333, 197 => 333, 198 => 333, 199 => 333,
                                       200 => 333, 202 => 333, 203 => 333, 205 => 333, 206 => 333,
                                       207 => 333, 208 => 1000, 225 => 1000, 227 => 300, 232 => 667,
                                       233 => 778, 234 => 1000, 235 => 330, 241 => 722, 245 => 278,
                                       248 => 278, 249 => 500, 250 => 722, 251 => 556);
            $this->widths['Times-Italic'] = array (32 => 250, 33 => 333, 34 => 420, 35 => 500, 36 => 500,
                                         37 => 833, 38 => 778, 39 => 333, 40 => 333, 41 => 333,
                                         42 => 500, 43 => 675, 44 => 250, 45 => 333, 46 => 250,
                                         47 => 278, 48 => 500, 49 => 500, 50 => 500, 51 => 500,
                                         52 => 500, 53 => 500, 54 => 500, 55 => 500, 56 => 500,
                                         57 => 500, 58 => 333, 59 => 333, 60 => 675, 61 => 675,
                                         62 => 675, 63 => 500, 64 => 920, 65 => 611, 66 => 611,
                                         67 => 667, 68 => 722, 69 => 611, 70 => 611, 71 => 722,
                                         72 => 722, 73 => 333, 74 => 444, 75 => 667, 76 => 556,
                                         77 => 833, 78 => 667, 79 => 722, 80 => 611, 81 => 722,
                                         82 => 611, 83 => 500, 84 => 556, 85 => 722, 86 => 611,
                                         87 => 833, 88 => 611, 89 => 556, 90 => 556, 91 => 389,
                                         92 => 278, 93 => 389, 94 => 422, 95 => 500, 96 => 333,
                                         97 => 500, 98 => 500, 99 => 444, 100 => 500, 101 => 444,
                                         102 => 278, 103 => 500, 104 => 500, 105 => 278, 106 => 278,
                                         107 => 444, 108 => 278, 109 => 722, 110 => 500, 111 => 500,
                                         112 => 500, 113 => 500, 114 => 389, 115 => 389, 116 => 278,
                                         117 => 500, 118 => 444, 119 => 667, 120 => 444, 121 => 444,
                                         122 => 389, 123 => 400, 124 => 275, 125 => 400, 126 => 541,
                                         161 => 389, 162 => 500, 163 => 500, 164 => 167, 165 => 500,
                                         166 => 500, 167 => 500, 168 => 500, 169 => 214, 170 => 556,
                                         171 => 500, 172 => 333, 173 => 333, 174 => 500, 175 => 500,
                                         177 => 500, 178 => 500, 179 => 500, 180 => 250, 182 => 523,
                                         183 => 350, 184 => 333, 185 => 556, 186 => 556, 187 => 500,
                                         188 => 889, 189 => 1000, 191 => 500, 193 => 333, 194 => 333,
                                         195 => 333, 196 => 333, 197 => 333, 198 => 333, 199 => 333,
                                         200 => 333, 202 => 333, 203 => 333, 205 => 333, 206 => 333,
                                         207 => 333, 208 => 889, 225 => 889, 227 => 276, 232 => 556,
                                         233 => 722, 234 => 944, 235 => 310, 241 => 667, 245 => 278,
                                         248 => 278, 249 => 500, 250 => 667, 251 => 500);
            $this->widths['Times-BoldItalic'] = array (32 => 250, 33 => 389, 34 => 555, 35 => 500, 36 => 500,
                                             37 => 833, 38 => 778, 39 => 333, 40 => 333, 41 => 333,
                                             42 => 500, 43 => 570, 44 => 250, 45 => 333, 46 => 250,
                                             47 => 278, 48 => 500, 49 => 500, 50 => 500, 51 => 500,
                                             52 => 500, 53 => 500, 54 => 500, 55 => 500, 56 => 500,
                                             57 => 500, 58 => 333, 59 => 333, 60 => 570, 61 => 570,
                                             62 => 570, 63 => 500, 64 => 832, 65 => 667, 66 => 667,
                                             67 => 667, 68 => 722, 69 => 667, 70 => 667, 71 => 722,
                                             72 => 778, 73 => 389, 74 => 500, 75 => 667, 76 => 611,
                                             77 => 889, 78 => 722, 79 => 722, 80 => 611, 81 => 722,
                                             82 => 667, 83 => 556, 84 => 611, 85 => 722, 86 => 667,
                                             87 => 889, 88 => 667, 89 => 611, 90 => 611, 91 => 333,
                                             92 => 278, 93 => 333, 94 => 570, 95 => 500, 96 => 333,
                                             97 => 500, 98 => 500, 99 => 444, 100 => 500, 101 => 444,
                                             102 => 333, 103 => 500, 104 => 556, 105 => 278, 106 => 278,
                                             107 => 500, 108 => 278, 109 => 778, 110 => 556, 111 => 500,
                                             112 => 500, 113 => 500, 114 => 389, 115 => 389, 116 => 278,
                                             117 => 556, 118 => 444, 119 => 667, 120 => 500, 121 => 444,
                                             122 => 389, 123 => 348, 124 => 220, 125 => 348, 126 => 570,
                                             161 => 389, 162 => 500, 163 => 500, 164 => 167, 165 => 500,
                                             166 => 500, 167 => 500, 168 => 500, 169 => 278, 170 => 500,
                                             171 => 500, 172 => 333, 173 => 333, 174 => 556, 175 => 556,
                                             177 => 500, 178 => 500, 179 => 500, 180 => 250, 182 => 500,
                                             183 => 350, 184 => 333, 185 => 500, 186 => 500, 187 => 500,
                                             188 => 1000, 189 => 1000, 191 => 500, 193 => 333, 194 => 333,
                                             195 => 333, 196 => 333, 197 => 333, 198 => 333, 199 => 333,
                                             200 => 333, 202 => 333, 203 => 333, 205 => 333, 206 => 333,
                                             207 => 333, 208 => 1000, 225 => 944, 227 => 266, 232 => 611,
                                             233 => 722, 234 => 944, 235 => 300, 241 => 722, 245 => 278,
                                             248 => 278, 249 => 500, 250 => 722, 251 => 500);
        }
        if (empty($params["font"])) {
            $font = "Helvetica";
        } else {
            $font = $params["font"];
            switch ($font) {
                case "Times-Roman" :
                    $font = "Times";
                    break;
                case "Helvetica-Oblique" :
                    $font = "Helvetica";
                    break;
                case "Helvetica-BoldOblique" :
                    $font = "Helvetica-Bold";
                    break;
                case "ZapfDingbats" :
                    $font = "Dingbats";
                    break;
            }
        }
        if (!isset($params["height"])) {
            $size = 12;
        } else {
            $size = $params["height"];
        }
        if (substr($font, 0, 7) == "Courier") {
            // Courier is a fixed-width font
            $width = strlen($string) * 600;
        } else {
            $width = 0;
            $len = strlen($string);
            for ($i = 0; $i < $len; $i++) {
             if (IsSet ($this->widths[$font][ord($string{$i})])) { $width += $this->widths[$font][ord($string{$i})];}
            }
        }
        // We now have the string width in font units
        return $width * $size / 1000;
    }

    function wrap_line(&$text, $width, $param = array())
    {
        $maxchars = (int)(1.1 * $width / $this->strlen("i", $param));
        $words = explode(" ", substr($text, 0, $maxchars));
        if ($this->strlen($words[0]) >= $width) {
            $final = $words[0];
        } else {
            $space = $this->strlen(" ", $param);
            $len = 0;
            $word = 0;
            $final = "";
            while ($len < $width) {
                if ($word >= count($words)) {
                    break;
                }
                $temp = $this->strlen($words[$word], $param);
                if ( ($len + $temp) <= $width) {
                    $final .= $words[$word] . " ";
                    $word ++;
                }
                $len += $space + $temp;
            }
        }
        $text = substr($text, strlen($final));
        return $final;
    }

    function word_wrap($words, $width, $param = array())
    {
        // break $words into an array separated by manual paragraph break character
        $paragraph = explode("\n", $words);
        // find the width of 1 space in this font
        $swidth = $this->strlen( " " , $param );
        // uses each element of $paragraph array and splits it at spaces
        for ($lc = 0; $lc < count($paragraph); $lc++){
            while (strlen($paragraph[$lc]) > 0) {
                $returnarray[] = $this->wrap_line($paragraph[$lc], $width, $param);
            }
        }
        return $returnarray;
    }

    function draw_one_paragraph($top, $left, $bottom, $right, $text, $page, $param = array())
    {
        if (!isset($param["height"]) || $param["height"] <= 0) {
            $param["height"] = 12;
        }
        if (!isset($param['align'])) {
            $param['align'] = 'left';
        }
        $height = 1.1 * $param['height'];
        $width = $right - $left;
        while ($top > $bottom) {
            if (strlen($text) < 1) {
                break;
            }
            $top -= $height;
            if ($top >= $bottom) {
                $line = $this->wrap_line($text, $width, $param);
                switch ($param['align']) {
                case 'right' :
                    $line = trim($line);
                    $l = $right - $this->strlen($line, $param);
                    break;

                case 'center' :
                    $line = trim($line);
                    $l = $left + (($width - $this->strlen($line, $param)) / 2);
                    break;
                
                default :
                    $l = $left;
                }
                $this->draw_text($l, $top, $line, $page, $param);
            } else {
                $top += $height;
                break;
            }
        }
        if (strlen($text) > 0) {
            return $text;
        } else {
            return $top;
        }
    }

    function draw_paragraph($top, $left, $bottom, $right, $text, $page, $param = array())
    {
        $paras = split("\n", $text);
        for ($i = 0; $i < count($paras); $i++) {
            $over = $this->draw_one_paragraph($top,
                                              $left,
                                              $bottom,
                                              $right,
                                              $paras[$i],
                                              $page,
                                              $param);
            if (is_string($over)) {
                break;
            }
            $top = $over;
        }
        $rv = $over;
        if ($i < count($paras)) {
            for ($x = $i + 1; $x < count($paras); $x++) {
                $rv .= "\n" . $paras[$x];
            }
        }
        return $rv;
    }

/******************************************************
 * These functions are internally used by the library *
 * and shouldn't really be called by a user of        *
 * phppdflib                                          *
 ******************************************************/

    function _resolve_colors(&$n, $attrib)
    {
        if (isset($attrib["red"])) {
           $n["sred"] = $attrib["red"];
           $n["fred"] = $attrib["red"];
        }
        if (isset($attrib["green"])) {
           $n["sgreen"] = $attrib["green"];
           $n["fgreen"] = $attrib["green"];
        }
        if (isset($attrib["blue"])) {
           $n["sblue"] = $attrib["blue"];
           $n["fblue"] = $attrib["blue"];
        }
        $temp = array('sred','sgreen','sblue','fred','fgreen','fblue');
        foreach ($temp as $colcomp) {
            if (isset($attrib[$colcomp])) {
                $n[$colcomp] = $attrib[$colcomp];
            }
        }
    }

    /* Check to see if a requested font is already in the
     * list, if not add it.  Either way, return the libid
     * of the font
     */
    function _use_font($id)
    {
        if ( isset($this->builddata["fonts"]) && count($this->builddata["fonts"]) > 0 ) {
            foreach ($this->builddata["fonts"] as $libid => $name) {
                if ($name == $id) {
                    return $libid;
                }
            }
        }
        /* The font isn't in the table, so we add it
         * and return it's ID
         */
        return $this->new_font($id);
    }

    /* Convert a big-endian byte stream into an integer */
    function _int_val($string)
    {
        $r = 0;
        for ($i = 0; $i < strlen($string); $i ++ ) {
            $r += ord($string{$i}) * pow(256, strlen($string) - $i -1);
        }
        return $r;
    }

    function _make_raw_image($liboid)
    {
        $s["Type"] = "/XObject";
        $s["Subtype"] = "/Image";
        $s["Width"] = $this->objects[$liboid]["width"];
        $s["Height"] = $this->objects[$liboid]["height"];
        $s["ColorSpace"] = $this->objects[$liboid]["colorspace"];
        $s["BitsPerComponent"] = $this->objects[$liboid]["bpc"];
        if ( strlen($this->objects[$liboid]["filter"]) > 0 ) {
            $s["Filter"] = $this->objects[$liboid]["filter"];
        }
        return $this->_streamify("", $this->objects[$liboid]["data"], $s);
    }

    function _place_raw_image($liboid)
    {
        $xscale = $this->objects[$liboid]["xscale"];
        $yscale = $this->objects[$liboid]["yscale"];
        $angle = $this->objects[$liboid]["rotation"];
        $temp = "q 1 0 0 1 " .
                $this->objects[$liboid]["left"] . " " .
                $this->objects[$liboid]["bottom"] . " cm ";
        if ($angle != 0) {
            $temp .= $this->_rotate($angle) . " cm ";
        }
        if ($xscale != 1 || $yscale != 1) {
            $temp .= "$xscale 0 0 $yscale 0 0 cm ";
        }
        $temp .= "/Img" . $this->objects[$liboid]["image"] .
                 " Do Q\x0a";
        return $temp;
    }

    function _rotate($angle)
    {
        $a = deg2rad($angle);
        $cos = cos($a);
        $sin = sin($a);
        $r = sprintf("%1\$01.6f %2\$01.6f %3\$01.6f %1\$01.6f 0 0", $cos, $sin, -$sin);
        return $r;
    }

    function _make_line($liboid)
    {
        $gstate = "";
        if ( $colortest = $this->_colorset($liboid) ) {
            $gstate .= $colortest . " ";
        }
        if ( isset($this->objects[$liboid]["width"]) && $this->objects[$liboid]["width"] != 1 ) {
            $gstate .= $this->objects[$liboid]["width"] . " w ";
        }
        $firstpoint = true;
        $temp = "";
        foreach ($this->objects[$liboid]["x"] as $pointid => $x) {
            $y = $this->objects[$liboid]["y"][$pointid];
            $temp .= $x . " " . $y . " ";
            if ($firstpoint) {
                $temp .= "m ";
                $firstpoint = false;
            } else {
                $temp .= "l ";
            }
        }
        $temp .= "S";
        if ( strlen($gstate) > 0 ) {
            $temp = "q " . $gstate . $temp . " Q";
        }
        return $temp . "\x0a";
    }

    function _make_rect($liboid)
    {
        $gstate = "";
        if ( $colortest = $this->_colorset($liboid) ) {
            $gstate .= $colortest . " ";
        }
        if ( isset($this->objects[$liboid]["width"]) && $this->objects[$liboid]["width"] != 1 ) {
            $gstate .= $this->objects[$liboid]["width"] . " w ";
        }
        $temp = $this->objects[$liboid]["left"] . " ";
        $temp .= $this->objects[$liboid]["bottom"];
        $temp .= " " . ( $this->objects[$liboid]["right"]
                 - $this->objects[$liboid]["left"] );
        $temp .= " " . ( $this->objects[$liboid]["top"]
                 - $this->objects[$liboid]["bottom"] );
        $temp .= " re S";
        if ( strlen($gstate) > 0 ) {
            $temp = "q " . $gstate . $temp . " Q";
        }
        return $temp . "\x0a";
    }

    function _make_text($liboid)
    {
        $statechange = ""; $locateinbt = true;
        $statechange = $this->_colorset($liboid);
        if ($this->objects[$liboid]["rotation"] != 0) {
            $statechange .= "1 0 0 1 " .
                            $this->objects[$liboid]["left"] . " " .
                            $this->objects[$liboid]["bottom"] . " cm " .
                            $this->_rotate($this->objects[$liboid]["rotation"]) .
                            " cm ";
            $locateinbt = false;
        }
        $temp = "BT ";
        if ($this->objects[$liboid]["mode"] != 0) {
            $temp .= $this->objects[$liboid]["mode"] .
                            " Tr ";
            // Adjust stroke width
            $statechange .= $this->objects[$liboid]["height"] / 35 . " w ";
        }
        $temp .= "/F" . $this->objects[$liboid]["font"] . " ";
        $temp .= $this->objects[$liboid]["height"];
        $temp .= " Tf ";
        if ($locateinbt) {
            $temp .= $this->objects[$liboid]["left"] . " " .
                     $this->objects[$liboid]["bottom"];
        } else {
            $temp .= "0 0";
        }
        $temp .= " Td ";
        $temp .= $this->_stringify($this->objects[$liboid]["text"]);
        $temp .= " Tj ";
        $temp .= "ET";
        if (strlen($statechange) > 0) {
            $temp = "q " . $statechange . $temp . " Q";
        }
        return $temp . "\x0a";
    }

    function _colorset($libid)
    {
        $red = isset($this->objects[$libid]["fred"]) ? (float)$this->objects[$libid]["fred"] : 0;
        $green = isset($this->objects[$libid]["fgreen"]) ? (float)$this->objects[$libid]["fgreen"] : 0;
        $blue = isset($this->objects[$libid]["fblue"]) ? (float)$this->objects[$libid]["fblue"] : 0;
        if (($red > 0) || ($green > 0) || ($blue > 0) ) {
            $r = $red . " " . $green . " " . $blue;
            $r .= " rg ";
        } else {
            $r = "";
        }
        $red = isset($this->objects[$libid]["sred"]) ? (float)$this->objects[$libid]["sred"] : 0;
        $green = isset($this->objects[$libid]["sgreen"]) ? (float)$this->objects[$libid]["sgreen"] : 0;
        $blue = isset($this->objects[$libid]["sblue"]) ? (float)$this->objects[$libid]["sblue"] : 0;
        if (($red > 0) || ($green > 0) || ($blue > 0) ) {
            $r .= $red . " " . $green . " " . $blue;
            $r .= " RG ";
        }
        return $r;
    }

    function _band_add_object($objarray, $bandid)
    {
        $oid = $this->_band_next_oid($bandid);
        $this->bands[$bandid]["objects"][$oid] = $objarray;
        return $oid;
    }

    function _band_next_oid($bandid)
    {
        $temp = $this->bands[$bandid]["next"];
        $this->bands[$bandid]["next"] ++;
        return $temp;
    }

    /* Sets the column counter to the top of the column
     * Used by the ->column_* funcitons
     */
    function _column_top()
    {
        $this->llop = $this->objects[$this->pageid]["height"] - $this->padding;
    }

    /* Used to determine what pdflib objects need converted
     * to actual PDF objects.
     */
    function _becomes_object($object)
    {
        if ($object == "null") {
            return false;
        }
        return true;
    }

    /* builds an array of child objects */
    function _get_kids($pdfid)
    {
        $libid = $this->pdftolib[$pdfid];
        foreach( $this->objects as $obid => $object ) {
            if (isset($object["parent"]) && $object["parent"] == $libid) {
                $kids[] = $this->libtopdf[$obid] . " 0 R";
            }
        }
        return $kids;
    }

    /* builds an array of pages, in order */
    function _order_pages($pdfid)
    {
        $libid = $this->pdftolib[$pdfid];
        foreach( $this->objects as $obid => $object ) {
            if (isset($object["parent"]) && $object["parent"] == $libid) {
                $kids[$object["number"]] = $this->libtopdf[$obid] . " 0 R";
            }
        }
        if (is_array ($kids)) { ksort($kids,SORT_NUMERIC); }
        return $kids;
    }

    /* simple helper function to return the current oid
     * and increment it by one
     */
    function _addnewoid()
    {
        $o = $this->nextoid;
        $this->nextoid++;
        return $o;
    }

    /* The xreftable will contain a list of all the
     * objects in the pdf file and the number of bytes
     * from the beginning of the file that the object
     * occurs. Each time we add an object, we call this
     * to record it's location, then call ->_genxreftable()
     * to generate the table from array
     */
    function _addtoxreftable($offset, $gennum)
    {
        $this->nextobj ++;
        $this->xreftable[$this->nextobj]["offset"] = $offset;
        $this->xreftable[$this->nextobj]["gennum"] = $gennum;
        $this->xreftable[$this->nextobj]["free"] = "n";
        return $this->nextobj;
    }

    function _genxreftable()
    {
        $rs = "xref\x0a0 " . (string)($this->nextobj + 1) . "\x0a";
        for ( $i = 0; $i <= $this->nextobj; $i ++ ) {
            $rs .= sprintf("%010u %05u %s \x0a", $this->xreftable[$i]["offset"],
                           $this->xreftable[$i]["gennum"],
                           $this->xreftable[$i]["free"]);
        }
        return $rs;
    }

    /* Returns a properly formatted pdf dictionary
     * of $name containing entries specified by
     * the array $entries
     */
    function _makedictionary($name, $entries)
    {
        $rs = $name . "<<\x0a";
        if (isset($entries) && count($entries) > 0) {
            foreach ($entries as $key => $value) {
                $rs .= "/" . $key . " " . $value . "\x0a";
            }
        }
        $rs .= ">>";
        return $rs;
    }

    /* returns a properly formatted pdf array */
    function _makearray($entries)
    {
        $rs = "[";
        if ( is_array($entries) ) {
            foreach ($entries as $entry) {
                $rs .= $entry . " ";
            }
        } else {
            $rs .= $entries;
        }
        $rs = rtrim($rs) . "]";
        return $rs;
    }

    /* Returns a properly formatted string, with any
     * special characters escaped
     */
    function _stringify($string)
    {
        // Escape potentially problematic characters
        $string = preg_replace("-\\\\-","\\\\\\\\",$string);
        $bad = array ("-\(-", "-\)-" );
        $good = array ("\\(", "\\)" );
        $string = preg_replace($bad,$good,$string);
        return "(" . rtrim($string) . ")";
    }

    function _streamify($name, $data, $sarray = array())
    {
        /* zlib compression is a compile time option
         * for php, thus we need to make sure it's
         * available before using it.
         */
        if ( function_exists('gzcompress') && $this->builddata["compress"] ) {
            // For now, we don't compress if already using a filter
            if ( !isset($sarray["Filter"]) || strlen($sarray["Filter"]) == 0 ) {
                $sarray["Filter"] = "/FlateDecode";
            } else {
                $sarray['Filter'] = "[/FlateDecode " . $sarray['Filter'] . "]";
            }
            $data = gzcompress($data, $this->builddata["compress"]);
        }
        $sarray["Length"] = strlen($data);
        $os = $this->_makedictionary($name, $sarray);
        $os .= "stream\x0a" . $data . "\x0aendstream";
        return $os;
    }

    /* Returns a properly formatted page node
     * page nodes with 0 kids are not created
     */
    function _makepagenode($kids, $addtlopts = false)
    {
        $parray["Type"] = "/Pages";
        if ( isset($kids) AND count($kids) > 0 ) {
            // Array of child objects
            $parray["Kids"] = $this->_makearray($kids);
            // Number of pages
            $parray["Count"] = count($kids);
        } else {
            // No kids is an error condition
            return false;
        }
        if ( is_array($addtlopts) ) {
            foreach ( $addtlopts as $key => $value ) {
                $parray[$key] = $value;
            }
        }

        /* The resource dictionary is always object 3
         */
        $parray["Resources"] = "3 0 R";

        $os = $this->_makedictionary("", $parray);
        $os = "obj" . $os . "endobj";
        return $os;
    }

    function _makepage($parent, $contents, $liboid)
    {
        $parray["Type"] = "/Page";
        $parray["Parent"] = $this->libtopdf[$parent] . " 0 R";
        $parray["Contents"] = $this->_makearray($contents);
        $parray["MediaBox"] = "[0 0 "
                            . $this->objects[$liboid]["width"] . " "
                            . $this->objects[$liboid]["height"] . "]";
        $os = $this->_makedictionary("", $parray);
        $os = "obj" . $os . "endobj";
        return $os;
    }

    function _maketrailer($info)
    {
        $rs = "trailer\x0a";
        $temp["Size"] = $this->nextobj + 1;
        $temp["Root"] = "1 0 R";
        $temp["Info"] = $info . " 0 R";
        $rs .= $this->_makedictionary("",$temp);
        $rs .= "\x0astartxref\x0a";
        $rs .= $this->builddata["startxref"] . "\x0a";
        return $rs;
    }
}

 /**
 * Fonction de convertion et d'extraction des donnees image au format JPG
 * @param string $fiche_photo Chemin d'acces a la photo et nom de du fichier image a traiter
 * @return string Donnees au format JPG de l'image
 */
 Function image_jpg ($fiche_photo)
  {
   Global $repertoire_racine, $repertoire_temporaire, $separateur_repertoire ;
   If (!IsSet ($repertoire_racine)) { $repertoire_temporaire = "..".$separateur_repertoire."..".$separateur_repertoire."tmp" ; }
   // Type d'image
   $info_image = GetImageSize ($fiche_photo) ;
   If ($info_image [2] != 2)
    {
     Switch ($info_image [2])
      {
       Case 1 : // Gif
                $source = @ImageCreateFromGif ($fiche_photo) ;
                Break ;
       Case 3 : // Png
                $source = @ImageCreateFromPng ($fiche_photo) ;
                Break ;
       Case 6 : // Bmp
                $source = @ImageCreateFromBmp ($fiche_photo) ;
                Break ;
       Case 16 : // Xpm
                $source = ImageCreateFromXpm ($fiche_photo) ;
                Break ;
      }
   /*If (($info_image [2] != IMG_JPG) And ($info_image [2] != IMG_JPEG))
    {
     Switch ($info_image [2])
      {
       Case IMG_GIF  : $source = ImageCreateFromGif ($fiche_photo) ; Break ;
       Case IMG_PNG  : $source = ImageCreateFromPng ($fiche_photo) ; Break ;
       Case IMG_WBMP : $source = ImageCreateFromBmp ($fiche_photo) ; Break ;
       Case IMG_XPM  : $source = ImageCreateFromXpm ($fiche_photo) ; Break ;
      }*/
     @ImageJpeg ($source, $repertoire_temporaire.$separateur_repertoire.Session_Id ().".jpg") ;
     @ImageDestroy ($source) ;
     $photo = @FOpen ($repertoire_temporaire.$separateur_repertoire.Session_Id ().".jpg", "r") ;
     $donnees = @FRead ($photo, @FileSize ($repertoire_temporaire.$separateur_repertoire.Session_Id ().".jpg")) ;
     @FClose ($photo) ;
     @UnLink ($repertoire_temporaire.$separateur_repertoire.Session_Id ().".jpg") ;
    }
   Else
    {
     $photo = FOpen ($fiche_photo, "r") ;
     $donnees = FRead ($photo, FileSize ($fiche_photo)) ;
     FClose ($photo) ;
    }
   Return $donnees ;
  }
?>